package model

import (
	myConfig "common/config"
	"common/helper"
	"database/sql"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"github.com/doug-martin/goqu/v9/exp"
)

type TblReportAgency struct {
	Id                string  `db:"id" json:"id"`
	MemCount          int     `db:"mem_count" json:"mem_count"`                     //人数
	DepositMemCount   int     `db:"deposit_mem_count" json:"deposit_mem_count"`     //充值人数
	FirstDepositBonus float64 `db:"first_deposit_bonus" json:"first_deposit_bonus"` //首充奖励
	ValidBetAmount    float64 `db:"valid_bet_amount" json:"valid_bet_amount"`       //流水
	RebateAmount      float64 `db:"rebate_amount" json:"rebate_amount"`             //下级返水
	TotalAmount       float64 `db:"total_amount" json:"total_amount"`               //总佣金
	Ty                int     `db:"ty" json:"ty"`
	ReportTime        int64   `db:"report_time" json:"report_time"`
	Lvl               string  `db:"lvl" json:"lvl"`
	Uid               string  `db:"uid" json:"uid"`
	Username          string  `db:"username" json:"username"`
}

type tblReportUser struct {
	Id                     string  `json:"id" db:"id"`
	Ty                     int     `json:"ty" db:"ty"`
	ReportTime             int64   `json:"report_time" db:"report_time"`
	Uid                    string  `json:"uid" db:"uid"`
	TotalCommissions       float64 `json:"total_commissions" db:"total_commissions"`                 //历史总佣金
	WaitCommissions        float64 `json:"wait_commissions" db:"wait_commissions"`                   //待结算佣金
	TotalTeamNum           int     `json:"total_team_num" db:"total_team_num"`                       //团队总人数
	DepositWithdrawDiff    float64 `json:"deposit_withdraw_diff" db:"deposit_withdraw_diff"`         //团队存取查
	DirectPushNum          int     `json:"direct_push_num" db:"direct_push_num"`                     //直推人数
	DirectPushDepositNum   int     `json:"direct_push_deposit_num" db:"direct_push_deposit_num"`     //直推充值人数
	DirectPushFdBonus      float64 `json:"direct_push_fd_bonus" db:"direct_push_fd_bonus"`           //直推首充奖励
	DirectPushDeposit      float64 `json:"direct_push_deposit" db:"direct_push_deposit"`             //直推充值
	DirectPushFlow         float64 `json:"direct_push_flow" db:"direct_push_flow"`                   //直推流水
	DirectPushFlowBonus    float64 `json:"direct_push_flow_bonus" db:"direct_push_flow_bonus"`       //直推流水奖励
	DirectPushDwDiff       float64 `json:"direct_push_dw_diff" db:"direct_push_dw_diff"`             //直推充提差
	DirectPushWaitFlow     float64 `json:"direct_push_wait_flow" db:"direct_push_wait_flow"`         //待结算直推流水
	DirectPushWaitBonus    float64 `json:"direct_push_wait_bonus" db:"direct_push_wait_bonus"`       //待结算直推流水奖励
	LvlSecondNum           int     `json:"lvl_second_num" db:"lvl_second_num"`                       //二级人数
	LvlSecondDepositNum    int     `json:"lvl_second_deposit_num" db:"lvl_second_deposit_num"`       //二级充值人数
	LvlSecondDepositAmount float64 `json:"lvl_second_deposit_amount" db:"lvl_second_deposit_amount"` ///二级充值金额
	LvlSecondFlow          float64 `json:"lvl_second_flow" db:"lvl_second_flow"`                     //二级流水
	LvlSecondFlowBonus     float64 `json:"lvl_second_flow_bonus" db:"lvl_second_flow_bonus"`         //二级流水奖励
	LvlSecondWaitFlow      float64 `json:"lvl_second_wait_flow" db:"lvl_second_wait_flow"`           //二级待结算流水
	LvlSecondWaitBonus     float64 `json:"lvl_second_wait_bonus" db:"lvl_second_wait_bonus"`         //二级待结算流水奖励
	LvlSecondDwDiff        float64 `json:"lvl_second_dw_diff" db:"lvl_second_dw_diff"`               //二级充提差
	LvlThreeNum            int     `json:"lvl_three_num" db:"lvl_three_num"`                         //三级人数
	LvlThreeDepositNum     int     `json:"lvl_three_deposit_num" db:"lvl_three_deposit_num"`         //三级充值人数
	LvlThreeDepositAmount  float64 `json:"lvl_three_deposit_amount" db:"lvl_three_deposit_amount"`   //三级充值金额
	LvlThreeFlow           float64 `json:"lvl_three_flow" db:"lvl_three_flow"`                       //三级流水
	LvlThreeFlowBonus      float64 `json:"lvl_three_flow_bonus" db:"lvl_three_flow_bonus"`           //三级流水奖励
	LvlThreeWaitFlow       float64 `json:"lvl_three_wait_flow" db:"lvl_three_wait_flow"`             //三级待结算流水
	LvlThreeWaitBonus      float64 `json:"lvl_three_wait_bonus" db:"lvl_three_wait_bonus"`           //三级待结算流水奖励
	LvlThreeDwDiff         float64 `json:"lvl_three_dw_diff" db:"lvl_three_dw_diff"`                 //三级充提差
	WithdrawAmount         float64 `json:"withdraw_amount" db:"withdraw_amount"`                     //提现金额
	Username               string  `json:"username" db:"username"`                                   //用户名
	CreatedAt              uint32  `json:"created_at" db:"created_at"`                               //注册时间
	CreatedIp              string  `json:"created_ip" db:"created_ip"`                               //注册ip
}

type listReportData struct {
	T int               `json:"t"`
	D []TblReportAgency `json:"d"`
}

type reportDetailData struct {
	TotalAmount   float64         `json:"total_amount"`
	SettledAmount float64         `json:"settled_amount"`
	PendingAmount float64         `json:"pending_amount"`
	LvlOne        TblReportAgency `json:"lvl_one"`
	LvlTwo        TblReportAgency `json:"lvl_two"`
	LvlThree      TblReportAgency `json:"lvl_three"`
}

func ReportDetail(uid string) (reportDetailData, error) {

	data := reportDetailData{}
	var userReport tblReportUser
	ex := g.Ex{"ty": 1, "uid": uid}
	query, _, _ := dialect.From("tbl_report_user").Select(colsReportUser...).Where(ex).ToSQL()
	err := meta.SlaveDB.Get(&userReport, query)
	if err != nil && err != sql.ErrNoRows {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), helper.DBErr)
	}
	if err == sql.ErrNoRows {
		return data, nil
	}

	data.TotalAmount = userReport.TotalCommissions
	data.SettledAmount = userReport.TotalCommissions
	data.PendingAmount = userReport.DirectPushWaitBonus + userReport.LvlSecondWaitBonus + userReport.LvlThreeWaitBonus
	data.LvlOne = TblReportAgency{
		TotalAmount:       userReport.DirectPushFdBonus + userReport.DirectPushFlowBonus,
		MemCount:          userReport.DirectPushNum,
		DepositMemCount:   userReport.DirectPushDepositNum,
		ValidBetAmount:    userReport.DirectPushFlow,
		RebateAmount:      userReport.DirectPushFlowBonus,
		FirstDepositBonus: userReport.DirectPushFdBonus,
	}

	data.LvlTwo = TblReportAgency{
		TotalAmount:       userReport.LvlSecondFlowBonus,
		MemCount:          userReport.LvlSecondNum,
		DepositMemCount:   userReport.LvlSecondDepositNum,
		ValidBetAmount:    userReport.LvlSecondFlow,
		RebateAmount:      userReport.LvlSecondFlowBonus,
		FirstDepositBonus: 0,
	}

	data.LvlThree = TblReportAgency{
		TotalAmount:       userReport.LvlThreeFlowBonus,
		MemCount:          userReport.LvlThreeNum,
		DepositMemCount:   userReport.LvlThreeDepositNum,
		ValidBetAmount:    userReport.LvlThreeFlow,
		RebateAmount:      userReport.LvlThreeFlowBonus,
		FirstDepositBonus: 0,
	}

	return data, nil
}

func ReportRecord(uid string, startTime, endTime string, lvl string, page, pageSize uint) (listReportData, error) {

	data := listReportData{}
	ex := g.Ex{"ty": 2, "uid": uid}
	if startTime != "" && endTime != "" {

		startAt, err := helper.TimeToLoc(startTime, loc)
		if err != nil {
			return data, errors.New(helper.DateTimeErr)
		}

		endAt, err := helper.TimeToLoc(endTime, loc)
		if err != nil {
			return data, errors.New(helper.DateTimeErr)
		}

		if startAt >= endAt {
			return data, errors.New(helper.QueryTimeRangeErr)
		}

		ex["report_time"] = g.Op{"between": exp.NewRangeVal(startAt, endAt+1)}
	}

	if page == 1 {
		query, _, _ := dialect.From("tbl_report_user").Select(g.COUNT("id")).Where(ex).Limit(1).ToSQL()
		err := meta.SlaveDB.Get(&data.T, query)
		if err != nil {
			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), helper.DBErr)
		}
		if data.T == 0 {
			return data, nil
		}
	}

	orderBy := "report_time"
	order := g.C(orderBy).Desc()
	var result []tblReportUser
	offset := (page - 1) * pageSize
	query, _, _ := dialect.From("tbl_report_user").Select(colsReportUser...).Where(ex).Order(order).Offset(offset).Limit(pageSize).ToSQL()
	err := meta.SlaveDB.Select(&result, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), helper.DBErr)
	}

	for _, userReport := range result {
		if lvl == "1" {
			data.D = append(data.D, TblReportAgency{
				ReportTime:        userReport.ReportTime,
				TotalAmount:       userReport.DirectPushFdBonus + userReport.DirectPushFlowBonus,
				MemCount:          userReport.DirectPushNum,
				DepositMemCount:   userReport.DirectPushDepositNum,
				ValidBetAmount:    userReport.DirectPushFlow,
				RebateAmount:      userReport.DirectPushFlowBonus,
				FirstDepositBonus: userReport.DirectPushFdBonus,
			})

		}
		if lvl == "2" {
			data.D = append(data.D, TblReportAgency{
				ReportTime:        userReport.ReportTime,
				TotalAmount:       userReport.LvlSecondFlowBonus,
				MemCount:          userReport.LvlSecondNum,
				DepositMemCount:   userReport.LvlSecondDepositNum,
				ValidBetAmount:    userReport.LvlSecondFlow,
				RebateAmount:      userReport.LvlSecondFlowBonus,
				FirstDepositBonus: 0,
			})
		}
		if lvl == "3" {
			data.D = append(data.D, TblReportAgency{
				ReportTime:        userReport.ReportTime,
				TotalAmount:       userReport.LvlThreeFlowBonus,
				MemCount:          userReport.LvlThreeNum,
				DepositMemCount:   userReport.LvlThreeDepositNum,
				ValidBetAmount:    userReport.LvlThreeFlow,
				RebateAmount:      userReport.LvlThreeFlowBonus,
				FirstDepositBonus: 0,
			})
		}
	}

	return data, nil
}

type InviteData struct {
	InviteNumber   int     `json:"invite_number"`   //有效邀请人数
	DistanceNumber int     `json:"distance_number"` //距离下一档邀请奖励还差多少有效邀请人数
	ReceiveAmount  float64 `json:"receive_amount"`  //已领取邀请奖励
	RewardAmount   float64 `json:"reward_amount"`   //下一档邀请奖励
}

type ProxyAccuInfo struct {
	ValidNum         int     `json:"valid_num" db:"valid_num"`
	ProxyInviteBonus float64 `json:"proxy_invite_bonus" db:"proxy_invite_bonus"`
}

func InviteDetail(uid string) (InviteData, error) {
	var data InviteData
	var proxyInfo ProxyAccuInfo
	var cfg myConfig.CsProxyInviteBonusCfg
	proxyCfg := cfg.GetCfg()

	sqlSelect := fmt.Sprintf("SELECT valid_num,proxy_invite_bonus FROM tbl_proxy_accu WHERE UID=%s and level=1", uid)
	GetMasterDBInstance().Get(&proxyInfo, sqlSelect)

	diff, nextBonus := calculateNextReward(proxyCfg, proxyInfo.ValidNum)

	data.DistanceNumber = diff
	data.RewardAmount = nextBonus
	data.InviteNumber = proxyInfo.ValidNum
	data.ReceiveAmount = proxyInfo.ProxyInviteBonus

	return data, nil
}

func calculateNextReward(inviteBonusList []myConfig.CfgProxyInviteBonusItem, currentValidCounts int) (int, float64) {
	for _, bonus := range inviteBonusList {
		if currentValidCounts < bonus.ValidCounts {
			nextValidCounts := bonus.ValidCounts
			nextBonus := bonus.Bonus
			diff := nextValidCounts - currentValidCounts
			return diff, nextBonus
		}
	}
	// 如果 currentValidCounts 超过或等于所有奖励层级，则表示已经达到最高档，返回0
	return 0, 0.00
}
